import { defineComponent, PropType, ref } from "vue";
import VirtualListCore from "./core";

export {default as VirtualListCore} from './core';

const CONTAINER_CLASSNAME = `cm-virtual-list`;
let globalContainerStylesheet: HTMLStyleElement;

const insertGlobalStylesheet = () => {
    if (!globalContainerStylesheet) {
        globalContainerStylesheet = document.createElement('style');
        globalContainerStylesheet.type = 'text/css';

        globalContainerStylesheet.textContent = `
        .${CONTAINER_CLASSNAME} {
            position: relative !important;
            flex-shrink: 0 !important;
            width: 100%;
            height: 100%;
            overflow: auto;
        }
        .${CONTAINER_CLASSNAME} > * {
            width: 100%;
            will-change: transform !important;
            box-sizing: border-box !important;
            contain: layout !important;
        }
      `;
        document.head.appendChild(globalContainerStylesheet);
    }
};

export interface CustomComponentProps {
    component: any,
    props: any,
}

export interface VirtualListProps {
    height?: number,
    maxHeight?: number,
    itemEstimatedSize: number
    overscan?: number,
    items: any[],
    onScroll?: (scrollTop: number) => void,
    itemComponent: CustomComponentProps, // 列表项组件
    ref?: any,
    displayDelay?: number,
}

export interface MeasuredData {
    size: number,
    offset: number,
}
export interface IMeasuredDataMap {
    [key: number]: MeasuredData
}

export default defineComponent({
    name: 'VirtualList',
    props: {
        height: {type: Number as PropType<VirtualListProps['height']>},
        maxHeight: {type: Number as PropType<VirtualListProps['maxHeight']>},
        itemEstimatedSize: {type: Number as PropType<VirtualListProps['itemEstimatedSize']>},
        overscan: {type: Number as PropType<VirtualListProps['overscan']>},
        items: {type: Array as PropType<VirtualListProps['items']>},
        itemComponent: {type: Object as PropType<VirtualListProps['itemComponent']>},
        displayDelay: {type: Number as PropType<VirtualListProps['displayDelay']>},
    },
    emits: ['scroll'],
    setup (props: VirtualListProps, { slots }) {
        insertGlobalStylesheet();
        const scrollElement = ref<any>();
        const contentElement = ref<any>();
        const bodyElement = ref<any>();
        const core = ref<any>();

        return () => <div class={CONTAINER_CLASSNAME} ref={scrollElement}>
            <div ref={contentElement}>
                <div ref={bodyElement}>
                    {
                        scrollElement.value
                            ? <VirtualListCore ref={core} scrollElement={scrollElement.value} contentElement={contentElement.value} bodyElement={bodyElement.value}
                                {...props} >
                                {{
                                    default: (...args) => {
                                        return slots.default?.(...args);
                                    }
                                }}
                            </VirtualListCore>
                            : null
                    }
                </div>
            </div>
        </div>;
    }
});
